﻿using System;
using System.Linq;
using System.Text;
using CharacterCreation.Data.Annotations;

namespace CharacterCreation.Data.QueryBuilders {
    public class UpdateBuilder {
        public static string UpdateQuery<T>(T entity, string[] properties) {
            TableAttribute tableAttribute = TableBuilder.GetTableAttribute<T>();
            StringBuilder builder = new StringBuilder();
            StringBuilder valueDefinitions = new StringBuilder();

            foreach (var pInfo in typeof(T).GetProperties()
                .Where(p => properties.Contains(p.Name))) {

                // skip if this item needs to be ignored
                if (pInfo.GetCustomAttributes(typeof(IgnoreAttribute), false).FirstOrDefault() != null) continue;

                // insert the comma after the different definitions
                if (!string.IsNullOrWhiteSpace(valueDefinitions.ToString())) valueDefinitions.Append("," + Environment.NewLine);

                //Get the result, when it's a datetime it needs to be reformatted
                object result = string.Empty;
                if (pInfo.PropertyType.ToString() == "System.DateTime")
                    result = ((DateTime)pInfo.GetValue(entity, null)).ToString("yyyy-MM-dd HH:mm:ss");
                else
                    result = pInfo.GetValue(entity, null);

                if (!appendQuotes(pInfo)) valueDefinitions.AppendFormat("[{0}] = {1}", pInfo.Name, result);
                else valueDefinitions.AppendFormat("[{0}] = '{1}'", pInfo.Name, result != null ? result.ToString().Replace("'", "''") : result);
            }

            builder.AppendFormat("update {0} set {1} where Id = '{2}'", tableAttribute.TableName, valueDefinitions, getIdValue(entity));
            return builder.ToString();
        }

        private static bool appendQuotes(System.Reflection.PropertyInfo pInfo) {
            switch (pInfo.PropertyType.ToString()) {
                case "System.String":
                    return true;
                case "System.Int16":
                case "System.Int32":
                case "System.Int64":
                    return false;
                case "System.Boolean":
                    return false;
                case "System.DateTime":
                    return true;
                case "System.Guid":
                    return true;
                default:
                    return true;
            }
        }

        private static string getIdValue<T>(T entity) {
            return typeof(T).GetProperty("Id").GetValue(entity, null).ToString();
        }

 
    }
}
